Vue分页组件的实现
撰写时间: 2019-09-20 总共: 5051 字 转载请注明: BY-SA 4.0(除特别声明或转载文章外)
Vue 简单分页
效果
实现效果:
使用
// 在父组件使用
<zeroPagination
:total="totals"
:current-page="current"
@changePage="change_page"
@changePageSize="change_pagesize"
:page-size="pageSize"
:simple="false"/>
参数
需要的参数为,
totals:数据总数
current-page:当前页
可指定的不必须参数
page-size:每页显示数据条数
返回当前页跟当前显示页数
Pagination.vue
<template>
<ul id="zero-pagination" v-if="pages!==1 && pages!==0">
<li :class="current === 1?'disabled':''">
<a href="javascript:;" @click="prev">
<i class="fas fa-angle-left"></i>
</a>
</li>
<li v-for="(node,index) in pageNodeList" :class="current === node.value?'active':''" :key="index">
<a v-if="node.text==='prevMore'" @click="prev">
<i class="fas fa-angle-double-left"></i>
</a>
<a href="javascript:;" @click="go(node.value)">
</a>
<a v-if="node.text==='nextMore'" @click="next">
<i class="fas fa-angle-double-right"></i>
</a>
</li>
<li :class="current === pages?'disabled':''">
<a href="javascript:;" @click="next">
<i class="fas fa-angle-right"></i>
</a>
</li>
<li v-if="!simple">
<a href="javascript:;" @click="first">
首页
</a>
</li>
<li v-if="!simple">
<a href="javascript:;" @click="last">
尾页
</a>
</li>
<li v-if="!simple">
<select v-model="currentPageSize" @change="setCurrentPageSize">
<!-- 不动态绑定value会得到一个字符串导致类型检测失败 -->
<option :value="5" selected>5</option>
<option :value=10>10</option>
<option :value=15>15</option>
<option :value=20>20</option>
</select>
</li>
</ul>
</template>
<script>
/**
* name:zeroPagination
* props:{
* total:Number
* currentPage:Number
* pageSize:Number
* pageNodes:Number 偶数会强制成奇数
* simple:Boolean
* }
* Function:{
* changePage return current
* changePageSize return currentPageSize
* }
*/
export default {
name:'zeroPagination',
data(){
return{
// 当前每页显示条数
currentPageSize:this.pageSize,
// 当前页
current:this.currentPage,
// 总记录数
size:this.total,
}
},
props:{
// 数据总数
total:{type:Number,default:0},
// 每页显示条数
pageSize:{type:Number,default:5},
// 当前页
currentPage:{type:Number,default:1},
// 可见页码数
pageNodes:{
// 指定分页项目最多个数
type:Number,
default:4,
// 强制转换为奇数
coerce:(v)=>{
v=v>0?v:10;
return v % 2 === 1?v:v+1;
}
},
simple:{
type:Boolean,
default:false
}
},
computed:{
// 总页数
pages:function(){
return Math.ceil(this.size/this.currentPageSize);
},
// 分页页码
pageNodeList:function(){
// 页码个数
const page_node_number = this.pageNodes;
// 总页数
const page_count = this.pages;
// 当前页
let current_page = this.current;
// 偏移量
const _offset = Math.floor(page_node_number/2);
const offset = {
start : current_page - _offset,
end: current_page + _offset,
}
let list = [];
if(offset.start < 1){
offset.end = offset.end + (1 - offset.start);
offset.start = 1;
}
if(offset.end > page_count){
offset.start = offset.start - (offset.end - page_count);
offset.end = page_count;
}
if(offset.start < 1){
offset.start = 1
}
for(let i = offset.start; i <= offset.end;i++){
list.push({
text:i,
value:i
});
}
let tempList = [];
if(offset.start > 1){
tempList.push({
text:'prevMore',
value:''
})
}
list.forEach(item=>tempList.push(item));
if(offset.end < page_count){
tempList.push({
text:'nextMore',
value:''
})
}
return tempList;
}
},
methods:{
setCurrentPageSize(){
this.$emit('changePageSize',this.currentPageSize);
},
prev(){
if (this.current > 1) {
this.go(this.current - 1)
}
},
next(){
if (this.current < this.pages) {
this.go(this.current + 1)
}
},
first(){
if (this.current !== 1) {
this.go(1)
}
},
last(){
if (this.current != this.pages) {
this.go(this.pages)
}
},
go (page) {
if (this.current !== page) {
this.current = page
//父组件通过change方法来接受当前的页码
this.$emit('changePage',this.current);
}
}
},
watch:{
currentPage(val) {
this.current = val || 1
},
pageSize(val) {
this.currentPageSize = val || 5
},
total(val) {
this.size = val || 0
},
currentPageSize(){
// 监听改变每页显示数
let pages = Math.ceil(this.size / this.currentPageSize);
if (this.currentPage > pages) {
this.current = pages;
this.$emit('changePage',this.current);
}
}
}
}
</script>
<style>
#zero-pagination {
margin-top: 20px;
text-align: center;
overflow: hidden;
display: table;
margin: 0 auto;
height: 50px;
}
#zero-pagination li{
height: 25px;
line-height: 25px;
color: #757575;
text-align: center;
text-decoration: none;
display: inline-block;
margin: 0 8px;
}
#zero-pagination a{
color: #757575;
}
#zero-pagination li.disabled{
display: none;
}
</style>
重点
依然是数据驱动,需要使用分页的父组件拥有一个数据列表,需要进行分页显示。
我们拥有的数据就是后台传递的数据总数,当前页。
传递给分页组件,监听当前页,总数,等基本的数据进行分页内数据的逻辑处理。
包括返回首页和到达尾页,
根据指定的显示多少页码来计算偏移量显示省略图标。
// 分页页码
pageNodeList:function(){
// 页码个数
const page_node_number = this.pageNodes;
// 总页数
const page_count = this.pages;
// 当前页
let current_page = this.current;
// 偏移量
const _offset = Math.floor(page_node_number/2);
const offset = {
start : current_page - _offset,
end: current_page + _offset,
}
// 储存 可渲染的页码
let list = [];
if(offset.start < 1){
offset.end = offset.end + (1 - offset.start);
offset.start = 1;
}
if(offset.end > page_count){
offset.start = offset.start - (offset.end - page_count);
offset.end = page_count;
}
if(offset.start < 1){
offset.start = 1
}
for(let i = offset.start; i <= offset.end;i++){
list.push({
text:i,
value:i
});
}
// 转换成带省略的数组
let tempList = [];
// 存在超出的部分添加如一个标志对象
if(offset.start > 1){
tempList.push({
text:'prevMore',
value:''
})
}
list.forEach(item=>tempList.push(item));
if(offset.end < page_count){
tempList.push({
text:'nextMore',
value:''
})
}
return tempList;
}